/**
 * @brief  Sparse Linear Algebra functions wrapper of cuSolver APIs
 *
 */

#ifndef CUSOLVER_SP_WRAPPER_H_
#define CUSOLVER_SP_WRAPPER_H_

#include <bridge/blas/cublas_v2_wrapper.h>
#include <bridge/sparse/cusparse_wrapper.h>
#include "cusolver_common_wrapper.h"
#include "mcsolverSp.h"

#define CUSOLVERSP_H_ MCSOLVER_CUSOLVER_SP_H_

#define cusolverSpContext mcsolverSpContext
#define cusolverSpHandle_t mcsolverSpHandle_t

#define csrqrInfo mcsolverCsrqrInfo
#define csrqrInfo_t mcsolverCsrqrInfo_t

#define cusolverSpCreate mcsolverSpCreate
#define cusolverSpDestroy mcsolverSpDestroy
#define cusolverSpSetStream mcsolverSpSetStream
#define cusolverSpGetStream mcsolverSpGetStream
#define cusolverSpXcsrissymHost mcsolverSpXcsrissymHost

/* -------- GPU linear solver by LU factorization
 *       solve A*x = b, A can be singular
 * [ls] stands for linear solve
 * [v] stands for vector
 * [lu] stands for LU factorization
 */
#define cusolverSpScsrlsvluHost mcsolverSpScsrlsvluHost
#define cusolverSpDcsrlsvluHost mcsolverSpDcsrlsvluHost
#define cusolverSpCcsrlsvluHost mcsolverSpCcsrlsvluHost
#define cusolverSpZcsrlsvluHost mcsolverSpZcsrlsvluHost

/* -------- GPU linear solver by QR factorization
 *       solve A*x = b, A can be singular
 * [ls] stands for linear solve
 * [v] stands for vector
 * [qr] stands for QR factorization
 */
#define cusolverSpScsrlsvqr mcsolverSpScsrlsvqr
#define cusolverSpDcsrlsvqr mcsolverSpDcsrlsvqr
#define cusolverSpCcsrlsvqr mcsolverSpCcsrlsvqr
#define cusolverSpZcsrlsvqr mcsolverSpZcsrlsvqr

/* -------- CPU linear solver by QR factorization
 *       solve A*x = b, A can be singular
 * [ls] stands for linear solve
 * [v] stands for vector
 * [qr] stands for QR factorization
 */
#define cusolverSpScsrlsvqrHost mcsolverSpScsrlsvqrHost
#define cusolverSpDcsrlsvqrHost mcsolverSpDcsrlsvqrHost
#define cusolverSpCcsrlsvqrHost mcsolverSpCcsrlsvqrHost
#define cusolverSpZcsrlsvqrHost mcsolverSpZcsrlsvqrHost

/* -------- CPU linear solver by Cholesky factorization
 *       solve A*x = b, A can be singular
 * [ls] stands for linear solve
 * [v] stands for vector
 * [chol] stands for Cholesky factorization
 *
 * Only works for symmetric positive definite matrix.
 * The upper part of A is ignored.
 */
#define cusolverSpScsrlsvcholHost mcsolverSpScsrlsvcholHost
#define cusolverSpDcsrlsvcholHost mcsolverSpDcsrlsvcholHost
#define cusolverSpCcsrlsvcholHost mcsolverSpCcsrlsvcholHost
#define cusolverSpZcsrlsvcholHost mcsolverSpZcsrlsvcholHost

/* -------- GPU linear solver by Cholesky factorization
 *       solve A*x = b, A can be singular
 * [ls] stands for linear solve
 * [v] stands for vector
 * [chol] stands for Cholesky factorization
 *
 * Only works for symmetric positive definite matrix.
 * The upper part of A is ignored.
 */
#define cusolverSpScsrlsvchol mcsolverSpScsrlsvchol
#define cusolverSpDcsrlsvchol mcsolverSpDcsrlsvchol
#define cusolverSpCcsrlsvchol mcsolverSpCcsrlsvchol
#define cusolverSpZcsrlsvchol mcsolverSpZcsrlsvchol

/* ----------- CPU least square solver by QR factorization
 *       solve min|b - A*x|
 * [lsq] stands for least square
 * [v] stands for vector
 * [qr] stands for QR factorization
 */
#define cusolverSpScsrlsqvqrHost mcsolverSpScsrlsqvqrHost
#define cusolverSpDcsrlsqvqrHost mcsolverSpDcsrlsqvqrHost
#define cusolverSpCcsrlsqvqrHost mcsolverSpCcsrlsqvqrHost
#define cusolverSpZcsrlsqvqrHost mcsolverSpZcsrlsqvqrHost

/* --------- CPU eigenvalue solver by shift inverse
 *      solve A*x = lambda * x
 *   where lambda is the eigenvalue nearest mu0.
 * [eig] stands for eigenvalue solver
 * [si] stands for shift-inverse
 */
#define cusolverSpScsreigvsiHost mcsolverSpScsreigvsiHost
#define cusolverSpDcsreigvsiHost mcsolverSpDcsreigvsiHost
#define cusolverSpCcsreigvsiHost mcsolverSpCcsreigvsiHost
#define cusolverSpZcsreigvsiHost mcsolverSpZcsreigvsiHost

/* --------- GPU eigenvalue solver by shift inverse
 *      solve A*x = lambda * x
 *   where lambda is the eigenvalue nearest mu0.
 * [eig] stands for eigenvalue solver
 * [si] stands for shift-inverse
 */
#define cusolverSpScsreigvsi mcsolverSpScsreigvsi
#define cusolverSpDcsreigvsi mcsolverSpDcsreigvsi
#define cusolverSpCcsreigvsi mcsolverSpCcsreigvsi
#define cusolverSpZcsreigvsi mcsolverSpZcsreigvsi

// ----------- enclosed eigenvalues
#define cusolverSpScsreigsHost mcsolverSpScsreigsHost
#define cusolverSpDcsreigsHost mcsolverSpDcsreigsHost
#define cusolverSpCcsreigsHost mcsolverSpCcsreigsHost
#define cusolverSpZcsreigsHost mcsolverSpZcsreigsHost

/* --------- CPU symrcm
 *   Symmetric reverse Cuthill McKee permutation
 *
 */
#define cusolverSpXcsrsymrcmHost mcsolverSpXcsrsymrcmHost

/* --------- CPU symmdq
 *   Symmetric minimum degree algorithm by quotient graph
 *
 */
#define cusolverSpXcsrsymmdqHost mcsolverSpXcsrsymmdqHost

/* --------- CPU symmdq
 *   Symmetric Approximate minimum degree algorithm by quotient graph
 *
 */
#define cusolverSpXcsrsymamdHost mcsolverSpXcsrsymamdHost

/* --------- CPU metis
 *   symmetric reordering
 */
#define cusolverSpXcsrmetisndHost mcsolverSpXcsrmetisndHost

/* --------- CPU zfd
 *  Zero free diagonal reordering
 */
#define cusolverSpScsrzfdHost mcsolverSpScsrzfdHost
#define cusolverSpDcsrzfdHost mcsolverSpDcsrzfdHost
#define cusolverSpCcsrzfdHost mcsolverSpCcsrzfdHost
#define cusolverSpZcsrzfdHost mcsolverSpZcsrzfdHost

/* --------- CPU permuation
 *   P*A*Q^T
 *
 */
#define cusolverSpXcsrperm_bufferSizeHost mcsolverSpXcsrperm_bufferSizeHost
#define cusolverSpXcsrpermHost mcsolverSpXcsrpermHost

/*
 *  Low-level API: Batched QR
 *
 */
#define cusolverSpCreateCsrqrInfo mcsolverSpCreateCsrqrInfo
#define cusolverSpDestroyCsrqrInfo mcsolverSpDestroyCsrqrInfo
#define cusolverSpXcsrqrAnalysisBatched mcsolverSpXcsrqrAnalysisBatched
#define cusolverSpScsrqrBufferInfoBatched mcsolverSpScsrqrBufferInfoBatched
#define cusolverSpDcsrqrBufferInfoBatched mcsolverSpDcsrqrBufferInfoBatched
#define cusolverSpCcsrqrBufferInfoBatched mcsolverSpCcsrqrBufferInfoBatched
#define cusolverSpZcsrqrBufferInfoBatched mcsolverSpZcsrqrBufferInfoBatched
#define cusolverSpScsrqrsvBatched mcsolverSpScsrqrsvBatched
#define cusolverSpDcsrqrsvBatched mcsolverSpDcsrqrsvBatched
#define cusolverSpCcsrqrsvBatched mcsolverSpCcsrqrsvBatched
#define cusolverSpZcsrqrsvBatched mcsolverSpZcsrqrsvBatched

#endif
